package omq.xml;

import java.util.Map;

import omq.constants.OMQConstants;
import omq.xml.element.OMQXmlElement;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


public class OMQXmlUtil extends OMQAXmlUtil{
	
	/**
	 * This is the implementation of the abstract method from the IXmlUtil interface.
	 * It gets an XML element and convert it to XmlElement object.
	 */
	public Object handleElement(Element e) {
		OMQXmlElement xmlElement = new OMQXmlElement();
		NodeList list = e.getChildNodes();
		xmlElement.setElementName(e.getNodeName());
		for(int i = 0; i < list.getLength(); i++){
			Node n = list.item(i);
			short nodeType = n.getNodeType();
			if(nodeType == Node.ELEMENT_NODE){
				Element innerElement =(Element) n;
				xmlElement.addElement((OMQXmlElement)handleElement(innerElement));
			}
			if(nodeType == Node.TEXT_NODE){
				xmlElement.setNodeValue(n.getNodeValue());
			}
		}
		return xmlElement;
	}
	
	
	public OMQXmlElement generateRequestXml(String action,Map params){
		
		OMQXmlElement root = new OMQXmlElement();
		root.setElementName(OMQConstants.DOCUMENT_ROOT_TAG);
		OMQXmlElement header = createRequestHeader(action);
		OMQXmlElement auth = createRequestAuthz((String)params.get(OMQConstants.MAP_PARAM_USER),(String)params.get(OMQConstants.MAP_PARAM_PASSWORD));
		OMQXmlElement queueMgr = createRequestMsg((String)params.get(OMQConstants.MAP_PARAM_QMGR_NAME),(String)params.get(OMQConstants.MAP_PARAM_QUEUE_NAME),transformObject(params.get(OMQConstants.MAP_PARAM_MESSAGE_CONTENT)),(String)params.get(OMQConstants.MAP_PARAM_MESSAGE_ID));
		OMQXmlElement session = createRequestSession((String)params.get(OMQConstants.MAP_PARAM_SESSION_ID),(String)params.get(OMQConstants.MAP_PARAM_SESSION_TRANSACTIONAL),(String)params.get(OMQConstants.MAP_PARAM_SESSION_NUM_OF_MSGS));

		root.addElement(queueMgr);
		root.addElement(header);
		root.addElement(auth);
		root.addElement(session);
		return root;
	}
	
	/**
	 * Creating the header element and its children :
	 *  <header>
	 *  	<version>0.1</version>
     *     	<action>[#CDATA]</action>
     *  </header>
	 */
	private OMQXmlElement createRequestHeader(String action){
		//Element header - The main header element, under it will be action element and version element
		OMQXmlElement header = new OMQXmlElement();
		header.setElementName(OMQConstants.HEADER_ELEMENT);
		header.setId(OMQConstants.HEADER_ELEMENT);		
		//Element version
		OMQXmlElement version = new OMQXmlElement();
		version.setElementName(OMQConstants.HEADER_VERSION_ELEMENT);
		version.setNodeValue(OMQConstants.HEADER_VERSION_VALUE);
		version.setId(OMQConstants.HEADER_VERSION_ELEMENT);
		//Element action
		OMQXmlElement actionEl = new OMQXmlElement();
		actionEl.setElementName(OMQConstants.HEADER_ACTION_ELEMENT);
		actionEl.setId(OMQConstants.HEADER_ACTION_ELEMENT);
		actionEl.setNodeValue(action);
		
		header.addElement(actionEl);
		header.addElement(version);
		
		return header;
	}
	
	/**
	 * Creating the Authentication element and its children :
	 *  <authentication>
     *      <password>[#CDATA]</password>
     *      <login>[#CDATA]</login>
     *	</authentication>
	 */
	private OMQXmlElement createRequestAuthz(String user,String pwd){
		//Element authentication - under root
		OMQXmlElement authentication = new OMQXmlElement();
		authentication.setElementName(OMQConstants.AUTHZ_ELEMENT);
		authentication.setId(OMQConstants.AUTHZ_ELEMENT);	
		//Element login
		OMQXmlElement login = new OMQXmlElement();
		login.setElementName(OMQConstants.AUTHZ_USER_ELEMENT);
		login.setId(OMQConstants.AUTHZ_USER_ELEMENT);
		login.setNodeValue(user);
		//Element login
		OMQXmlElement password = new OMQXmlElement();
		password.setElementName(OMQConstants.AUTHZ_PASSWORD_ELEMENT);
		password.setId(OMQConstants.AUTHZ_PASSWORD_ELEMENT);
		password.setNodeValue(pwd);
		
		authentication.addElement(password);
		authentication.addElement(login);
		return authentication;
	}

	/**
	 * Creating the queue manager element and its children :
	 * <queue_manager>
	 * 	   <name>[#CDATA]</name>
	 *     <queue>
	 *     		<name>[#CDATA]</name>
	 *          <message>
	 *              <body>[#CDATA]</body>
	 *          </message>
	 *      </queue>
	 *  </queue_manager>
	 */
	private OMQXmlElement createRequestMsg(String queueMgrName,String queueName, String msg,String messageId){
		OMQXmlElement queueMgr = new OMQXmlElement();
		queueMgr.setElementName(OMQConstants.QUEUE_MANAGER_ELEMENT);
		queueMgr.setId(OMQConstants.QUEUE_MANAGER_ELEMENT);
		OMQXmlElement queueMgrNameEl = new OMQXmlElement();
		queueMgrNameEl.setElementName(OMQConstants.QUEUE_MANAGER_NAME_ELEMENT);
		queueMgrNameEl.setId(OMQConstants.QUEUE_MANAGER_NAME_ELEMENT);
		queueMgrNameEl.setNodeValue(queueMgrName);
		
		
		OMQXmlElement queue = new OMQXmlElement();
		queue.setElementName(OMQConstants.QUEUE_ELEMENT);
		queue.setId(OMQConstants.QUEUE_ELEMENT);
		OMQXmlElement queueNameEl = new OMQXmlElement();
		queueNameEl.setElementName(OMQConstants.QUEUE_NAME_ELEMENT);
		queueNameEl.setId(OMQConstants.QUEUE_NAME_ELEMENT);
		queueNameEl.setNodeValue(queueName);
		queue.addElement(queueNameEl);
		
		queueMgr.addElement(queueMgrNameEl);
		queueMgr.addElement(queue);
		if((msg != null && !msg.equals("")) || (messageId != null && !messageId.equals(""))){
			OMQXmlElement message = new OMQXmlElement();
			message.setElementName(OMQConstants.MESSAGE_ELEMENT);
			OMQXmlElement msgId = new OMQXmlElement();
			msgId.setElementName(OMQConstants.MESSAGE_ID_ELEMENT);
			msgId.setId(OMQConstants.MESSAGE_ID_ELEMENT);
			msgId.setNodeValue(messageId);
			message.addElement(msgId);
			
			OMQXmlElement msgBody = new OMQXmlElement();
			msgBody.setElementName(OMQConstants.MESSAGE_BODY_ELEMENT);
			msgBody.setId(OMQConstants.MESSAGE_BODY_ELEMENT);
			msgBody.setNodeValue(msg.toString());
			message.addElement(msgBody);
			queue.addElement(message);
		}
		
		return queueMgr;
	}

	/**
	 * <session>
	 * <id>[#CDATA]</id>
     * <transactional>true/false</transactional>
     * <number_of_messages>0</number_of_messages>
     * </session>
	 */
	private OMQXmlElement createRequestSession(String sessionId,String transactional, String numOfMessages){
		//Creating session root element
		OMQXmlElement sessionEl = new OMQXmlElement();
		sessionEl.setElementName(OMQConstants.SESSION_ELEMENT);
		sessionEl.setId(OMQConstants.SESSION_ELEMENT);
		
		//Creating child elements(as shown in the above method comment)
		OMQXmlElement session_idEl = new OMQXmlElement();
		session_idEl.setElementName(OMQConstants.SESSION_ID_ELEMENT);
		session_idEl.setId(OMQConstants.SESSION_ID_ELEMENT);
		session_idEl.setNodeValue(sessionId);
		System.out.println("session id : " + sessionId);
		OMQXmlElement isTransactionEl = new OMQXmlElement();
		isTransactionEl.setElementName(OMQConstants.SESSION_IS_TRANSACTION_ELEMENT);
		isTransactionEl.setId(OMQConstants.SESSION_IS_TRANSACTION_ELEMENT);
		isTransactionEl.setNodeValue(transactional);
		
		OMQXmlElement numOfMsgsEl = new OMQXmlElement();
		numOfMsgsEl.setElementName(OMQConstants.SESSION_NUM_OF_MESSAGES_ELEMENT);
		numOfMsgsEl.setId(OMQConstants.SESSION_NUM_OF_MESSAGES_ELEMENT);
		numOfMsgsEl.setNodeValue(numOfMessages);
		
		
		sessionEl.addElement(session_idEl);
		sessionEl.addElement(isTransactionEl);
		sessionEl.addElement(numOfMsgsEl);
		
		return sessionEl;
	}
}


